#ifndef COMMON_H
#define COMMON_H
#define _GNU_SOURCE
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define SAFEMALLOC(type) ({  \
    int siz = sizeof(type);  \
    type *ptr = malloc(siz); \
    if (ptr == NULL)         \
        goto err;            \
    ptr;                     \
});

#define SET_NONBLOCK(fd)                                      \
    {                                                         \
        do                                                    \
        {                                                     \
            int flags = fcntl(fd, F_GETFL, 0);                \
            if (flags == -1)                                  \
                goto err;                                     \
            if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) \
                goto err;                                     \
        } while (0);                                          \
    }
struct MagicPck
{
    uint16_t magic;
    struct sockaddr addr;
};
#define CONTINUE -1000
#define SERVER_SEND 2025
#define PEER_SEND 1996
#define PEER_CONNEC_PEER_1 1001
#define PEER_CONNEC_PEER_2 1002
#define PEER_CONNEC_PEER_3 1003
#define PEER_CONNEC_PEER_CHAT 7777
#define SERVER "192.168.2.110"
#define SERVER_PORT "7777"
#define CLIENT "192.168.5.5"
#define CLIENT_PORT "5555"
#define CLIENT2 "192.168.5.5"
#define CLIENT2_PORT "5555"
#define ELOG(fmt, ...) printf("\033[33m[ WARNING ] \033[0m" fmt "\n", ##__VA_ARGS__)
#define SLOG(fmt, ...) printf("\033[32m[ SUCCESS ] \033[0m" fmt "\n", ##__VA_ARGS__)
#define ADDRLOG(addr, title)                                                 \
    {                                                                        \
        do                                                                   \
        {                                                                    \
            struct sockaddr_in *p = (struct sockaddr_in *)addr;              \
            SLOG(title "%s:%d", inet_ntoa(p->sin_addr), ntohs(p->sin_port)); \
        } while (0);                                                         \
    }
#define PRINT_PTR(ptr, type, title)            \
    do                                         \
    {                                          \
        printf(title "\n");                         \
        uint8_t *p = (uint8_t *)(ptr);           \
        for (int i = 0; i < sizeof(type); i++) \
        {                                      \
            printf("%x ", p[i]);               \
            if (i % 16 == 0 && i != 0)         \
            {                                  \
                printf("\n");                  \
            }                                  \
        }                                      \
        printf("\n");                          \
    } while (0);

struct MagicPck *safe_recv_from(int fd);
int safe_send_to(int fd, const struct sockaddr *t);
struct sockaddr *gen_peer(const struct MagicPck *pck);
struct MagicPck *gen_magic_pck(int fd);
void log_magic_pck(const struct MagicPck *pck);
void start();
#endif
